[AWS CDK v2] Lambda 関数のエラー出力を AWS ChatBot で Slack 通知する仕組みを作ってみた

[AWS CDK v2] Lambda 関数のエラー出力を AWS ChatBot で Slack 通知する仕組みを作ってみた

Clock Icon2023.06.08

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、CX事業本部 Delivery部の若槻です。

AWS ChatBot を使うと、Slack や Amazon Chime などのチャットクライアントに AWS のアラート通知を送信する仕組みを簡単に構成することができます。

今回は、Lambda 関数のエラー出力を AWS ChatBot で Slack 通知する仕組みを AWS CDK v2 で作ってみました。

やってみた

AWS Chatbot で通知先 Slack ワークスペースの構成

まず AWS Chatbot で通知先 Slack ワークスペースの構成を行います。Slack 認証を伴うためこの部分は手作業が必要です。

AWS Chatbot コンソールにアクセスし、チャットクライアントの種類として Slack を選択し、クライアントを構成します。

許可したい Slack ワークスペースを指定します。

AWS Chatbot との連携を求められるので許可します。

すると AWS Chatbot コンソールで クライアントとして Slack ワークスペースが構成されます。ここでワークスペース ID を控えておきます。アラート通知の送信先となるチャンネルは後ほど AWS CDK で構成します。

これにより Slack ワークスペースに "aws" アプリが追加されます。

通知先 Slack チャンネルIDの確認

通知先チャンネルIDも確認して控えておきます。

チャンネルIDは Slack クライアントから確認できます。方法は下記が参考になります。

aws アプリの通知先チャンネルへの追加

aws アプリを通知先チャンネルに追加します。

Slack クライアントで次のスラッシュコマンドを実行し、"aws" アプリを通知先チャンネルに追加します。

/invite @aws

追加できました。

AWS CDK 実装

AWS CDK v2(2.77.0)および TypeScript で、監視に必要な AWS リソースを実装します。

import {
  aws_lambda_nodejs,
  aws_logs,
  aws_sns,
  aws_cloudwatch,
  aws_cloudwatch_actions,
  aws_chatbot,
  Duration,
  Stack,
  StackProps,
} from 'aws-cdk-lib';
import { Construct } from 'constructs';

const YOUR_WORKSPACE_ID = process.env.YOUR_WORKSPACE_ID || '';
const YOUR_CHANNEL_ID = process.env.YOUR_CHANNEL_ID || '';

export class CdkSampleStack extends Stack {
  constructor(scope: Construct, id: string, props: StackProps) {
    super(scope, id, props);

    // 監視対象の Lambda 関数の作成
    new aws_lambda_nodejs.NodejsFunction(this, 'sampleFunc', {
      functionName: 'sampleFunc',
    });

    // SNS トピックの作成
    const alarmtTopic = new aws_sns.Topic(this, 'alarmtTopic', {
      topicName: 'alarmtTopic',
    });

    // SNS トピックに対するアラームアクションの作成
    const alarmAction = new aws_cloudwatch_actions.SnsAction(alarmtTopic);

    // SNS トピックに対する Slack 通知の設定
    new aws_chatbot.SlackChannelConfiguration(
      this,
      'sampleSlackChannelConfiguration',
      {
        slackChannelConfigurationName: 'slackChannelConfiguration',
        slackChannelId: YOUR_CHANNEL_ID,
        slackWorkspaceId: YOUR_WORKSPACE_ID,
        notificationTopics: [alarmtTopic],
      }
    );

    // 監視対象の Lambda 関数の CloudWatch Logs グループの作成
    const sampleFuncLogGroup = new aws_logs.LogGroup(
      this,
      'sampleFuncLogGroup',
      {
        logGroupName: '/aws/lambda/sampleFunc',
      }
    );

    // "ERROR" という文字列の出力を監視する CloudWatch Logs メトリクスフィルターの作成
    const sampleFuncErrorMetricFilter = new aws_logs.MetricFilter(
      this,
      'sampleFuncErrorMetricFilter',
      {
        logGroup: sampleFuncLogGroup,
        metricNamespace: 'Lambda/SampleFunc', // "AWS/" から始まる名前空間は予約されているため使用できない
        metricName: 'Error',
        filterPattern: { logPatternString: 'ERROR' },
      }
    );

    // CloudWatch Logs メトリクスフィルターのメトリクスの作成
    const sampleFuncErrorMetric = sampleFuncErrorMetricFilter.metric({
      period: Duration.minutes(1),
      statistic: aws_cloudwatch.Stats.SUM,
    });

    // メトリクスを監視する CloudWatch アラームの作成
    const sampleFuncErrorAlarm = new aws_cloudwatch.Alarm(
      this,
      'sampleFuncErrorAlarm',
      {
        alarmName: 'sampleFuncErrorAlarm',
        metric: sampleFuncErrorMetric,
        threshold: 1,
        evaluationPeriods: 1,
        treatMissingData: aws_cloudwatch.TreatMissingData.NOT_BREACHING,
      }
    );

    // CloudWatch アラームに対するアクションの設定
    sampleFuncErrorAlarm.addAlarmAction(alarmAction);
    sampleFuncErrorAlarm.addOkAction(alarmAction);
  }
}

Lambda ハンドラーのコードは次のようになります。実行されると "ERROR!" という文字列をコンソール出力します。

export const handler = (): void => {
  console.log('ERROR!');
};

これにより次のような仕組みが構築できます。

  1. Lambda 関数が CloudWatch Logs に "ERROR" という文字列を含むイベントログを出力する
  2. CloudWatch Logs メトリクスフィルターが "ERROR" という文字列を含むイベントログを監視する
  3. CloudWatch Logs メトリクスフィルターによりメトリクスが CloudWatch に記録される
  4. CloudWatch アラームがメトリクスを監視する
  5. CloudWatch アラームがアラーム状態になった際に SNS トピックに通知する
  6. SNS トピックが AWS Chatbot に通知する

動作確認

Lambda 実行によりフィルター対象の文字列を CloudWatch Logs に出力します。

すると、Slack チャンネルにアラーム通知が投稿されました。

アラーム通知のリンクにアクセスすると、トリガーとなった Lambda 関数の CloudWatch Alarm の画面を開くことができます。Error メトリクスが記録されてアラーム状態となっていることが分かります。

アラームに対して OK アクションも設定しているので、アラームが OK 状態に戻った際にも Slack チャンネルに通知が投稿されます。

おわりに

Lambda 関数のエラー出力を AWS ChatBot で Slack 通知する仕組みを AWS CDK v2 で作ってみました。

CDK v1 を使う記事は下記が今まであったのですが、v2 版は無かったため書いてみるに至りました。

Slack の API を直接叩いたりすることなく簡単に Slack 通知の仕組みを作れるのはとても便利ですね。

また今回は Lambda 関数に対するカスタムメトリクスを利用した通知を構成しましたが、AWS リソースの組み込みのメトリクスを利用することも可能です。その場合は今回の CDK テンプレートを応用できると思います。

以上

この記事をシェアする

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.